using System;
using System.Collections.Generic;
using System.Text;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.Security;

using Impact.Infrastructure;
using Impact.Infrastructure.Plugins;
using Impact.Model.Objects;
using Impact.Model.Service;
using StructureMap;
using Impact.Controllers;
using System.Web.UI.HtmlControls;
using Impact.Infrastructure.Exceptions;

namespace Impact.Plugins
{
    /// <summary>
    /// Plugin for Article functionality.  Articles can be edited through the general Admin interface,
    /// and then the Article plugin can be placed on each page independantly of other articles, and 
    /// options set for that particular plugin.
    /// </summary>
    public class ArticlePlugin : IImpactPlugin
    {
        #region IImpactPlugin Members

        private static Guid _id = new Guid("BEB8AAB9-E154-4751-A50C-B1DF90E9E17B");
        private ArticlePluginAdmin _admin;

        /// <summary>
        /// CategoryId parameter name
        /// </summary>
        public const string CategoryId = "CategoryId";
        /// <summary>
        /// Headline parameter name
        /// </summary>
        public const string Headline = "Headline";

        /// <summary>
        /// default constructor
        /// </summary>
        public ArticlePlugin()
        {
            _admin = new ArticlePluginAdmin();
        }

        /// <summary>
        /// Gets the unique identifier for this Type
        /// </summary>
        public Guid PluginId
        {
            get { return _id; }
        }

        /// <summary>
        /// Gets the friendly textual description of this plugin
        /// </summary>
        public string Name
        {
            get { return "Article Listing"; }
        }

        /// <summary>
        /// Gets the listing of parameters and their types for configuration in the Admin screen
        /// </summary>
        public Dictionary<string, PluginParameter> Parameters
        {
            get
            {
                Dictionary<string, PluginParameter> output = new Dictionary<string, PluginParameter>();

                output.Add(CategoryId, new PluginParameter(this, CategoryId, typeof(Int32), true));
                output.Add(Headline, new PluginParameter(this, Headline, typeof(string), false));

                return output;
            }
        }

        /// <summary>
        /// Gets the Admin interface to be used to configure an instance of this plugin
        /// </summary>
        public IPluginAdmin Admin
        {
            get
            {
                return _admin;
            }
        }

        /// <summary>
        /// Renders the Article Plugin based on the parameter data configured by the Administrator. 
        /// Generates a composite control and returns the base Control.
        /// </summary>
        public void Render(Control container, Dictionary<string, PluginParameter> parameterValues)
        {
            if (parameterValues[CategoryId].Value == null) throw new UserException("Article Listing Plugin: Invalid setting for Display Category");
            int categoryId = Int32.Parse(parameterValues[CategoryId].Value);

            HtmlGenericControl div = new HtmlGenericControl( "div" );
            div.Attributes.Add("class", "article");
            container.Controls.Add( div );

            IArticleService service = ObjectFactory.GetInstance<IArticleService>();
            ArticleCollection articles = service.FetchByCategory(categoryId, true);

            foreach (Article article in articles)
            {
                string url = container.Page.ResolveClientUrl(ContentPresenter.FormatUrl(article));

                HtmlGenericControl title = new HtmlGenericControl("div");
                title.InnerHtml = string.Format("<a href=\"{0}\" class=\"article_title\">{1}</a>", url, article.Title );
                div.Controls.Add(title);

                HtmlGenericControl body = new HtmlGenericControl("div");
                body.Attributes.Add("class", "article_body");
                body.InnerHtml = article.Body;
                div.Controls.Add(body);

                MembershipUser user = Membership.GetUser(new Guid(article.CreatedBy));
                HtmlGenericControl footer = new HtmlGenericControl("div");
                footer.Attributes.Add("class", "article_footer");
                footer.InnerHtml = string.Format("Posted by {0} on {1}. <a href=\"{2}\">[{3} comments]</a>",
                    user.UserName, article.CreatedOn, url, article.Comments.Count);
                div.Controls.Add(footer);

            }

        }

        #endregion
    }


}
